﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Detection : MonoBehaviour
{
    #region Attributs
    private List<Vector2> _visibleTiles;
    private Archeologist _archeo;
    private EnemyMove _enemyMove;
    private Vector2 _oldPosition;
    private Vector2 _newPosition;
    private bool _detection;

    
    #endregion

    #region Properties
    public List<Vector2> VisibleTiles
    {
        get { return _visibleTiles; }
        set { _visibleTiles = value; }
    }

    #endregion

    #region Methods
    void Start()
    {
        _oldPosition = new Vector2(this.transform.position.x, this.transform.position.z);
        SetViewDetection();
        _archeo = FindObjectOfType(typeof(Archeologist)) as Archeologist;
        _enemyMove = FindObjectOfType(typeof(EnemyMove)) as EnemyMove;
    }


    public void Activate(bool active)
    {
        if (_visibleTiles == null)
            _visibleTiles = new List<Vector2>();

        _detection = active;

        if (active)
            return;
        foreach (Vector2 v in _visibleTiles)
        {
            Tile tile = LevelManager.Instance.GetTileAt(new Vector2(v.x, v.y));
            if(tile != null)
                tile.IsHighLighted = false;
        }
       
    }

    void Update()
    {
        if (!_detection)
            return;

        UpdateVisibleTiles();
    }

    /// <summary>
    /// 
    /// </summary>
    void UpdateVisibleTiles()
    {
        _newPosition = new Vector2((int)this.transform.position.x, (int)this.transform.position.z);
        if (_newPosition == _oldPosition)
            SetTilesVisibility(_newPosition, true);
        else
        {
            SetTilesVisibility(_oldPosition, false);
            _oldPosition = _newPosition;
        }

        if (IsPlayerInRange() && IsPlayerVisible())
            _archeo.suicideMe();
    }

    /// <summary>
    /// Throws a ray from this enemy to player position.
    /// Checks if nothing is between them.
    /// </summary>
    /// <returns>is player visible</returns>
    bool IsPlayerVisible()
    {
        RaycastHit hit;
        Vector3 enemyPos = new Vector3(_newPosition.x, 0.6f, _newPosition.y);
        Vector3 archeoPos = new Vector3(_archeo.TilePosition.x, 0.6f, _archeo.TilePosition.y);
        if (Physics.Raycast(enemyPos, (archeoPos - enemyPos).normalized, out hit))
        {
            // If player is hited
            if (Const.LAYER_PLAYER == hit.transform.gameObject.layer)
                return true;
        }
        return false;
    }

    /// <summary>
    /// Checks if player is in the detection range
    /// </summary>
    /// <returns>is player in range</returns>
    bool IsPlayerInRange()
    {
        if (null == _archeo)
            return false;

        Tile tile = null;
        int x, y;
        foreach (Vector2 vec2 in _visibleTiles)
        {
            // Get tile position from enemy position
            x = (int)this.transform.position.x + (int)vec2.x;
            y = (int)this.transform.position.z + (int)vec2.y;


            // Check if tile is in grid
            if ((LevelManager.Instance.NbTilesX > x && 0 <= x)
                && (LevelManager.Instance.NbTilesY > y && 0 <= y))
            {
                tile = LevelManager.Instance.GetTileAt(new Vector2(x, y));
                // if tile position and CurrentArcheologist position or equals
                // Then CurrentArcheologist is in range
                if (tile.position2D == _archeo.TilePosition)
                    return true;
            }
        }

        return false;
    }

    /// <summary>
    /// Sets the visibility of all tiles in _visibleTiles
    /// </summary>
    /// <param name="visible">is tile visible</param>
    void SetTilesVisibility(Vector2 enemyPosition, bool visible)
    {
        if (null == _enemyMove)
            return;

        Tile tile = null;
        int x, y;
        foreach (Vector2 vec2 in _visibleTiles)
        {
            // Get tile position from enemy position
            x = (int)enemyPosition.x + (int)vec2.x;
            y = (int)enemyPosition.y + (int)vec2.y;
            
            switch(_enemyMove._direction)
            {
                case Const.ACdirection.RIGHT:
                    break;
                case Const.ACdirection.LEFT:
                    break;
                case Const.ACdirection.UP:
                    break;
                case Const.ACdirection.DOWN:
                    break;
            }
            // Check if tile is in grid
            if ((LevelManager.Instance.NbTilesX > x && 0 <= x)
                && (LevelManager.Instance.NbTilesY > y && 0 <= y))
            {
                tile = LevelManager.Instance.GetTileAt(new Vector2(x, y));
                if (Const.TYPE_TILE.GROUND == tile.type)
                {
                    tile.IsHighLighted = visible; // Set visibility
                    tile.SetType(Const.TYPE_TILE.GROUND);
                }
            }
        }
    }

    void SetViewDetection()
    {
        var enemyCompo = GetComponent<Enemy>();
        if(null == enemyCompo)
            return;

        switch (enemyCompo.Type)
        {
            case Const.ENNEMY_TYPE.SQUELETTE:
                #region Coords
                _visibleTiles = new List<Vector2>()
                {
                    new Vector2( 0, -1),
                    new Vector2(-1,  0),
                    new Vector2( 0,  0),
                    new Vector2( 1,  0),
                    new Vector2( 0,  1),
				};
                #endregion
                break;
            case Const.ENNEMY_TYPE.MOMIE:
                #region Coords
                _visibleTiles = new List<Vector2>()
                {
                    new Vector2( 2,  0),
                    new Vector2( 0, -2),
                    new Vector2(-1, -1),
                    new Vector2( 0, -1),
                    new Vector2( 1, -1),
                    new Vector2(-2,  0),
                    new Vector2(-1,  0),
                    new Vector2( 0,  0),
                    new Vector2( 1,  0),
                    new Vector2(-1,  1),
                    new Vector2( 0,  1),
                    new Vector2( 1,  1),
                    new Vector2( 0,  2),
                };
                #endregion
                break;
            case Const.ENNEMY_TYPE.CAT:
                #region Coords
                _visibleTiles = new List<Vector2>()
                {
                    
                    new Vector2( 0, -2),
                    new Vector2( 0, -1),
                    new Vector2( 1,  1),
                    new Vector2(-1, -1),
                    new Vector2( 1, -1),
                    new Vector2(-1,  1),
                    new Vector2(-2,  0),
                    new Vector2(-1,  0),
                    new Vector2( 0,  0),
                    new Vector2( 1,  0),
                    new Vector2( 2,  0),
                    new Vector2( 0,  1),
                    new Vector2( 0,  2),
                };
                #endregion
                break;
            case Const.ENNEMY_TYPE.MONK:
                #region Coords
                _visibleTiles = new List<Vector2>()
                {
                    new Vector2( 0, -3),

                    new Vector2(-1, -2),
                    new Vector2( 0, -2),
                    new Vector2( 1, -2),

                    new Vector2(-2, -1),
                    new Vector2(-1, -1),
                    new Vector2( 0, -1),
                    new Vector2( 1, -1),

                    new Vector2( 2, -1),
                    new Vector2(-3,  0),
                    new Vector2(-2,  0),
                    new Vector2(-1,  0),
                    new Vector2( 0,  0),
                    new Vector2( 1,  0),
                    new Vector2( 2,  0),
                    new Vector2( 3,  0),
        
                    new Vector2(-2,  1),
                    new Vector2(-1,  1),
                    new Vector2( 0,  1),
                    new Vector2( 1,  1),
                    new Vector2( 2,  1),

                    new Vector2(-1,  2),
                    new Vector2( 0,  2),
                    new Vector2( 1,  2),
        
                    new Vector2( 0,  3),
                };
                #endregion
                break;
            case Const.ENNEMY_TYPE.ARTEFACT:
                #region Coords
                _visibleTiles = new List<Vector2>()
                {
                    new Vector2( 0, -3),

                    new Vector2(-1, -2),
                    new Vector2( 0, -2),
                    new Vector2( 1, -2),

                    new Vector2(-2, -1),
                    new Vector2(-1, -1),
                    new Vector2( 0, -1),
                    new Vector2( 1, -1),

                    new Vector2( 2, -1),
                    new Vector2(-3,  0),
                    new Vector2(-2,  0),
                    new Vector2(-1,  0),
                    new Vector2( 0,  0),
                    new Vector2( 1,  0),
                    new Vector2( 2,  0),
                    new Vector2( 3,  0),
        
                    new Vector2(-2,  1),
                    new Vector2(-1,  1),
                    new Vector2( 0,  1),
                    new Vector2( 1,  1),
                    new Vector2( 2,  1),

                    new Vector2(-1,  2),
                    new Vector2( 0,  2),
                    new Vector2( 1,  2),
        
                    new Vector2( 0,  3),
                };
                #endregion
                break;
        }
    }
    #endregion
}
